package com.uniflow.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uniflow.common.PageResult;
import com.uniflow.entity.Form;
import com.uniflow.mapper.FormMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 表单服务类
 */
@Service
@Transactional
public class UniflowFormService extends ServiceImpl<FormMapper, Form> {
    
    @Autowired
    private FormMapper formMapper;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    /**
     * 分页查询表单列表
     */
    public PageResult<Form> getFormList(int pageNum, int pageSize, String name, 
                                        String category, Boolean published, Boolean enabled, 
                                        String createdBy, boolean includeUsage) {
        Page<Form> page = new Page<>(pageNum, pageSize);
        IPage<Form> result = formMapper.selectFormPage(page, name, category, published, enabled, createdBy);
        
        // 解析JSON字段
        result.getRecords().forEach(this::parseJsonFields);
        
        return new PageResult<Form>(pageNum, pageSize, result.getTotal(), result.getRecords());
    }
    
    /**
     * 根据ID查询表单详情
     */
    public Form getFormById(String id) {
        Form form = this.getById(id);
        if (form != null) {
            parseJsonFields(form);
        }
        return form;
    }
    
    /**
     * 根据名称查询表单
     */
    public Form getFormByName(String name) {
        return formMapper.selectByName(name, null);
    }
    
    /**
     * 创建表单
     */
    public Form createForm(Form form) {
        // 检查表单名称是否重复
        if (formMapper.selectByName(form.getName(), null) != null) {
            throw new RuntimeException("表单名称已存在");
        }
        
        // 设置默认值
        form.setId(UUID.randomUUID().toString());
        form.setVersion(1);
        form.setPublished(false);
        form.setEnabled(true);
        
        if (form.getSortOrder() == null) {
            Integer maxSortOrder = formMapper.getMaxSortOrder();
            form.setSortOrder(maxSortOrder + 1);
        }
        
        // 序列化JSON字段
        serializeJsonFields(form);
        
        this.save(form);
        return form;
    }
    
    /**
     * 更新表单
     */
    public Form updateForm(Form form) {
        Form existingForm = this.getById(form.getId());
        if (existingForm == null) {
            throw new RuntimeException("表单不存在");
        }
        
        // 检查表单名称是否重复
        if (!existingForm.getName().equals(form.getName())) {
            if (formMapper.selectByName(form.getName(), form.getId()) != null) {
                throw new RuntimeException("表单名称已存在");
            }
        }
        
        // 序列化JSON字段
        serializeJsonFields(form);
        
        this.updateById(form);
        return form;
    }
    
    /**
     * 删除表单
     */
    public void deleteForm(String id) {
        Form form = this.getById(id);
        if (form == null) {
            throw new RuntimeException("表单不存在");
        }
        
        // 检查表单是否被使用
        int usageCount = formMapper.checkFormUsage(id);
        if (usageCount > 0) {
            throw new RuntimeException("表单已被使用，无法删除");
        }
        
        this.removeById(id);
    }
    
    /**
     * 批量删除表单
     */
    public void batchDeleteForms(List<String> ids) {
        for (String id : ids) {
            deleteForm(id);
        }
    }
    
    /**
     * 发布表单
     */
    public void publishForm(String id, String updatedBy, String updatedByName) {
        Form form = this.getById(id);
        if (form == null) {
            throw new RuntimeException("表单不存在");
        }
        
        formMapper.updatePublishStatus(id, true, updatedBy, updatedByName);
    }
    
    /**
     * 发布表单（简化版本）
     */
    public void publishForm(String id) {
        Form form = formMapper.selectById(id);
        if (form != null) {
            form.setPublished(true);
            form.setUpdatedAt(LocalDateTime.now());
            formMapper.updateById(form);
        }
    }
    
    /**
     * 取消发布表单
     */
    public void unpublishForm(String id, String updatedBy, String updatedByName) {
        formMapper.updatePublishStatus(id, false, updatedBy, updatedByName);
    }
    
    /**
     * 取消发布表单（简化版本）
     */
    public void unpublishForm(String id) {
        Form form = formMapper.selectById(id);
        if (form != null) {
            form.setPublished(false);
            form.setUpdatedAt(LocalDateTime.now());
            formMapper.updateById(form);
        }
    }
    
    /**
     * 启用表单
     */
    public void enableForm(String id) {
        Form form = formMapper.selectById(id);
        if (form != null) {
            form.setEnabled(true);
            form.setUpdatedAt(LocalDateTime.now());
            formMapper.updateById(form);
        }
    }
    
    /**
     * 禁用表单
     */
    public void disableForm(String id) {
        Form form = formMapper.selectById(id);
        if (form != null) {
            form.setEnabled(false);
            form.setUpdatedAt(LocalDateTime.now());
            formMapper.updateById(form);
        }
    }
    
    /**
     * 启用/禁用表单
     */
    public void updateFormStatus(String id, Boolean enabled, String updatedBy, String updatedByName) {
        Form form = this.getById(id);
        if (form == null) {
            throw new RuntimeException("表单不存在");
        }
        
        formMapper.updateEnabledStatus(id, enabled, updatedBy, updatedByName);
    }
    
    /**
     * 复制表单
     */
    public Form copyForm(String sourceId, String newName, String newTitle, 
                         String createdBy, String createdByName) {
        Form sourceForm = this.getById(sourceId);
        if (sourceForm == null) {
            throw new RuntimeException("源表单不存在");
        }
        
        // 检查新表单名称是否重复
        if (formMapper.selectByName(newName, null) != null) {
            throw new RuntimeException("表单名称已存在");
        }
        
        String newId = UUID.randomUUID().toString();
        formMapper.copyForm(sourceId, newId, newName, newTitle, createdBy, createdByName);
        
        return this.getById(newId);
    }
    
    /**
     * 批量更新表单排序
     */
    public void batchUpdateSortOrder(List<Form> forms) {
        formMapper.batchUpdateSortOrder(forms);
    }
    
    /**
     * 根据分类查询表单列表
     */
    public List<Form> getFormsByCategory(String category) {
        List<Form> forms = formMapper.selectByCategory(category);
        forms.forEach(this::parseJsonFields);
        return forms;
    }
    
    /**
     * 查询已发布的表单列表
     */
    public List<Form> getPublishedForms() {
        List<Form> forms = formMapper.selectPublishedForms();
        forms.forEach(this::parseJsonFields);
        return forms;
    }
    
    /**
     * 查询表单分类列表
     */
    public List<String> getFormCategories() {
        return formMapper.selectCategories();
    }
    
    /**
     * 检查表单名称是否可用
     */
    public boolean isFormNameAvailable(String name, String excludeId) {
        return formMapper.selectByName(name, excludeId) == null;
    }
    
    /**
     * 获取表单统计信息
     */
    public Map<String, Object> getFormStatistics() {
        return formMapper.getFormStatistics();
    }
    
    /**
     * 获取表单使用统计
     */
    public List<Map<String, Object>> getFormUsageStatistics(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        return formMapper.getFormUsageStatistics(limit);
    }
    
    /**
     * 根据创建人统计表单数量
     */
    public List<Map<String, Object>> getFormCountByCreator() {
        return formMapper.getFormCountByCreator();
    }
    
    /**
     * 根据分类统计表单数量
     */
    public List<Map<String, Object>> getFormCountByCategory() {
        return formMapper.getFormCountByCategory();
    }
    
    /**
     * 根据外部ID查询表单
     */
    public Form getFormByExternalId(String externalId) {
        Form form = formMapper.selectByExternalId(externalId);
        if (form != null) {
            parseJsonFields(form);
        }
        return form;
    }
    
    /**
     * 增加表单版本
     */
    public void incrementFormVersion(String id, String updatedBy, String updatedByName) {
        formMapper.incrementVersion(id, updatedBy, updatedByName);
    }
    
    /**
     * 解析JSON字段
     */
    private void parseJsonFields(Form form) {
        try {
            // 解析字段JSON
            if (StringUtils.hasText(form.getFieldsJson())) {
                List<Form.FormField> fields = objectMapper.readValue(
                        form.getFieldsJson(), new TypeReference<List<Form.FormField>>() {});
                form.setFields(fields);
            }
            
            // 解析配置JSON
            if (StringUtils.hasText(form.getConfigJson())) {
                Form.FormConfig config = objectMapper.readValue(
                        form.getConfigJson(), Form.FormConfig.class);
                form.setConfig(config);
            }
            
            // 解析样式JSON
            if (StringUtils.hasText(form.getStyleJson())) {
                Form.FormStyle style = objectMapper.readValue(
                        form.getStyleJson(), Form.FormStyle.class);
                form.setStyle(style);
            }
        } catch (Exception e) {
            // 忽略JSON解析错误
        }
    }
    
    /**
     * 序列化JSON字段
     */
    private void serializeJsonFields(Form form) {
        try {
            // 序列化字段
            if (form.getFields() != null) {
                form.setFieldsJson(objectMapper.writeValueAsString(form.getFields()));
            }
            
            // 序列化配置
            if (form.getConfig() != null) {
                form.setConfigJson(objectMapper.writeValueAsString(form.getConfig()));
            }
            
            // 序列化样式
            if (form.getStyle() != null) {
                form.setStyleJson(objectMapper.writeValueAsString(form.getStyle()));
            }
        } catch (Exception e) {
            throw new RuntimeException("序列化表单JSON字段失败", e);
        }
    }
    
    /**
     * 验证表单字段
     */
    public void validateForm(Form form) {
        if (!StringUtils.hasText(form.getName())) {
            throw new RuntimeException("表单名称不能为空");
        }
        
        if (!StringUtils.hasText(form.getTitle())) {
            throw new RuntimeException("表单标题不能为空");
        }
        
        if (form.getFields() == null || form.getFields().isEmpty()) {
            throw new RuntimeException("表单字段不能为空");
        }
        
        // 验证字段名称唯一性
        long distinctCount = form.getFields().stream()
                .map(Form.FormField::getName)
                .distinct()
                .count();
        
        if (distinctCount != form.getFields().size()) {
            throw new RuntimeException("表单字段名称不能重复");
        }
    }
    
    /**
     * 验证表单字段列表
     */
    public Map<String, Object> validateFormFields(List<Form.FormField> fields) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        
        if (fields == null || fields.isEmpty()) {
            errors.add("表单字段不能为空");
        } else {
            // 验证字段名称唯一性
            long distinctCount = fields.stream()
                    .map(Form.FormField::getName)
                    .distinct()
                    .count();
            
            if (distinctCount != fields.size()) {
                errors.add("表单字段名称不能重复");
            }
            
            // 验证每个字段
            for (Form.FormField field : fields) {
                if (!StringUtils.hasText(field.getName())) {
                    errors.add("字段名称不能为空");
                }
                if (!StringUtils.hasText(field.getLabel())) {
                    errors.add("字段标签不能为空");
                }
                if (!StringUtils.hasText(field.getType())) {
                    errors.add("字段类型不能为空");
                }
            }
        }
        
        result.put("valid", errors.isEmpty());
        result.put("errors", errors);
        return result;
    }
    
    /**
     * 生成表单预览HTML
     */
    public String generateFormPreviewHtml(String formId) {
        Form form = this.getFormById(formId);
        if (form == null) {
            throw new RuntimeException("表单不存在");
        }
        
        StringBuilder html = new StringBuilder();
        html.append("<form>");
        
        if (form.getFields() != null) {
            for (Form.FormField field : form.getFields()) {
                html.append(generateFieldHtml(field));
            }
        }
        
        html.append("</form>");
        return html.toString();
    }
    
    /**
     * 生成字段HTML
     */
    private String generateFieldHtml(Form.FormField field) {
        StringBuilder html = new StringBuilder();
        html.append("<div class='form-field'>");
        html.append("<label>").append(field.getLabel());
        if (Boolean.TRUE.equals(field.getRequired())) {
            html.append("<span class='required'>*</span>");
        }
        html.append("</label>");
        
        switch (field.getType()) {
            case "text":
            case "email":
            case "password":
            case "number":
                html.append("<input type='").append(field.getType()).append("' ");
                html.append("name='").append(field.getName()).append("' ");
                if (StringUtils.hasText(field.getPlaceholder())) {
                    html.append("placeholder='").append(field.getPlaceholder()).append("' ");
                }
                html.append("/>");
                break;
            case "textarea":
                html.append("<textarea name='").append(field.getName()).append("' ");
                if (StringUtils.hasText(field.getPlaceholder())) {
                    html.append("placeholder='").append(field.getPlaceholder()).append("' ");
                }
                html.append("></textarea>");
                break;
            case "select":
                html.append("<select name='").append(field.getName()).append("'>");
                // 这里可以根据options生成选项
                html.append("</select>");
                break;
            default:
                html.append("<input type='text' name='").append(field.getName()).append("' />");
        }
        
        if (StringUtils.hasText(field.getHelpText())) {
            html.append("<small class='help-text'>").append(field.getHelpText()).append("</small>");
        }
        
        html.append("</div>");
        return html.toString();
    }
    

    
    /**
     * 批量更新表单排序
     */
    public void batchUpdateSort(List<FormSort> formSorts) {
        if (formSorts != null && !formSorts.isEmpty()) {
            for (FormSort formSort : formSorts) {
                Form form = formMapper.selectById(formSort.getId());
                if (form != null) {
                    form.setSortOrder(formSort.getSortOrder());
                    form.setUpdatedAt(LocalDateTime.now());
                    formMapper.updateById(form);
                }
            }
        }
    }
    
    /**
     * 表单排序数据结构
     */
    public static class FormSort {
        private String id;
        private Integer sortOrder;
        
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
    }
}